package eva.savant.core.service

import org.springframework.orm.jpa.JpaTransactionManager
import net.sf.jasperreports.engine.data.JRCsvDataSource
import org.springframework.stereotype.Repository
import net.sf.jasperreports.engine.export.*
import net.sf.jasperreports.engine.*
import javax.annotation.Resource

@Repository(value = 'reportService')
public class ReportServiceImpl implements ReportService {


  private String pathReport

  @Resource(name= 'transaction')
  private JpaTransactionManager em


  public ReportServiceImpl() {

    pathReport= getClass().getResource('/').path.replace('WEB-INF/classes/','')+'resources/report/'

    println 'Path Report: ' + pathReport
  }

  public byte[] reportToXLS(String nameReport, HashMap parameters) throws Exception {

    def jasperPrint = JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,em.dataSource.connection)

    def arrayOutput = new ByteArrayOutputStream()


    def exporter = new JRXlsExporter()

    exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE)

    exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE)

    exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,Boolean.TRUE)

    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)

    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, arrayOutput)

    exporter.exportReport()

    return arrayOutput.toByteArray()
  }

  public byte[] reportToXLS(String nameReport, HashMap parameters, String cvsSource) throws Exception {

    def jasperPrint = JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,getDataSource(cvsSource))

    def arrayOutput = new ByteArrayOutputStream()


    def exporter = new JRXlsExporter()

    exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE)

    //exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE)

    exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,Boolean.TRUE)

    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)

    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, arrayOutput)

    exporter.exportReport()

    return arrayOutput.toByteArray()
  }

  public byte[] reportToPDF(String nameReport, HashMap parameters, String cvsSource) throws Exception {

    def jasperPrint = JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,getDataSource(cvsSource))

    def arrayOutput = new ByteArrayOutputStream()


    def exporter = new JRPdfExporter()

    //exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE)

    //exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE)

    //exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,Boolean.TRUE)

    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)

    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, arrayOutput)

    exporter.exportReport()

    return arrayOutput.toByteArray()
  }

  public byte[] reportToPDF(String nameReport, HashMap parameters) throws Exception {

    def jasperPrint = JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,em.dataSource.connection)

    def arrayOutput = new ByteArrayOutputStream()


    def exporter = new JRPdfExporter()

    //exporter.setParameter(JRXlsExporterParameter.IS_WHITE_PAGE_BACKGROUND,Boolean.FALSE)

    //exporter.setParameter(JRXlsExporterParameter.IS_REMOVE_EMPTY_SPACE_BETWEEN_ROWS,Boolean.TRUE)

    //exporter.setParameter(JRXlsExporterParameter.IS_DETECT_CELL_TYPE,Boolean.TRUE)

    exporter.setParameter(JRExporterParameter.JASPER_PRINT, jasperPrint)

    exporter.setParameter(JRExporterParameter.OUTPUT_STREAM, arrayOutput)

    exporter.exportReport()

    return arrayOutput.toByteArray()
  }

  public String reportToTXT(String nameReport, HashMap parameters) throws Exception {

    try {

      parameters= (HashMap<String,Object>) parameters

      def print= JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,em.dataSource.connection)

      def file= new File(pathReport, nameReport + '.txt')

      JRTextExporter exporter = new JRTextExporter()

      exporter.setParameter(JRTextExporterParameter.JASPER_PRINT, print)

      exporter.setParameter(JRTextExporterParameter.OUTPUT_FILE, file)

      exporter.setParameter(JRTextExporterParameter.CHARACTER_ENCODING,'ISO-8859-1')

      exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Float(5.0))

      exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Float(12.0))

      exporter.exportReport()

      return getFormatStringFromFile(file)

    } catch (JRException e) { e.printStackTrace(); throw new Exception('Error al exportar el reporte: ' + nameReport, e)

	} catch (Exception e) { e.printStackTrace(); throw new Exception('Error al generar el reporte: ' + nameReport, e) }

  }

  public String reportToTXT(String nameReport, HashMap parameters, String cvsSource) throws Exception {

    try {

      def print = JasperFillManager.fillReport(pathReport+'/'+nameReport+'.jasper',parameters,getDataSource(cvsSource))

      def file= new File(pathReport,nameReport + '.txt')


      def exporter = new JRTextExporter()

      exporter.setParameter(JRTextExporterParameter.JASPER_PRINT, print)

      exporter.setParameter(JRTextExporterParameter.OUTPUT_FILE, file)

      exporter.setParameter(JRTextExporterParameter.CHARACTER_ENCODING,'ISO-8859-1')

      exporter.setParameter(JRTextExporterParameter.CHARACTER_WIDTH, new Float(5.0))

      exporter.setParameter(JRTextExporterParameter.CHARACTER_HEIGHT, new Float(12.0))

      exporter.exportReport()

      return getFormatStringFromFile(file)

    } catch (JRException e) { e.printStackTrace(); throw new Exception('Error al exportar el reporte: ' + nameReport, e)

    } catch (Exception e) { e.printStackTrace(); throw new Exception('Error al generar el reporte: ' + nameReport, e) }

  }

  private JRCsvDataSource getDataSource(String cvsSource) {

    def dataSource= new JRCsvDataSource(new ByteArrayInputStream(cvsSource.getBytes('UTF-8')))

    dataSource.recordDelimiter= '\n'

    dataSource.fieldDelimiter= (char) ','

    dataSource.useFirstRowAsHeader= true

    return dataSource
  }

  private String getFormatStringFromFile(File file) throws Exception {

    def text=''

    def reader= new BufferedReader(new FileReader(file))

    def linea= reader.readLine()

    while(linea != null) {

    text= text + linea +'\r\n'

    linea= reader.readLine()
    }

    if(text.length() > 3) text= text.substring(0,text.length()-4)
       println text
    return text
  }

}